home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / rawcons.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  8KB  |  414 lines

  1. /*
  2.  * A "raw console" session manager.  This is sort of a high-speed version of
  3.  * "curses" --- but uses the current terminal type, instead of either a dumb
  4.  * terminal or ANSI X3.64 emulation.  It's a little smarter than "dumb", but
  5.  * not much.
  6.  */
  7.  
  8. #include <curses.h>
  9. #include <term.h>
  10. #undef FALSE
  11. #undef TRUE
  12. #include <sys/types.h>
  13. #include <termios.h>
  14. #include "hardware.h"
  15. #include "proc.h"
  16. #include "socket.h"
  17. #include "tty.h"
  18. #include "sessmgr.h"
  19. #undef tputs
  20. #include "config.h"
  21.  
  22. #ifdef SM_RAW
  23.  
  24. /*
  25.  * ought to share these... they're going to be identical between raw and curses
  26.  */
  27.  
  28. struct keytrie
  29. {
  30.     enum {KT_DEF, KT_TRIE, KT_TVAL, KT_VAL} kt_type; /* type of entry */
  31.     int kt_tval;        /* if a TVAL, the timed-out value */
  32.     union
  33.     {
  34.     struct keytrie *ktu_trie; /* sub-trie */
  35. #define kt_trie kt_u.ktu_trie
  36.     int ktu_val;        /* value */
  37. #define kt_val kt_u.ktu_val
  38.     } kt_u;
  39. };
  40.  
  41. static struct termios old_tty, new_tty;
  42. static int Suspense, infoed;
  43. static struct keytrie *keys;
  44. static TERMINAL *my_term;
  45.  
  46. static void
  47. key_init(void)
  48. {
  49.     int i;
  50.  
  51.     keys = mallocw(256 * sizeof *keys);
  52.     for (i = 256; i--; )
  53.     {
  54.     keys[i].kt_type = KT_DEF;
  55.     keys[i].kt_val = i;
  56.     }
  57. }
  58.  
  59. static void
  60. key_add(const char *str, int val)
  61. {
  62.     const char *old;
  63.     struct keytrie *t;
  64.     int c, i;
  65.  
  66.     /*
  67.      * Follow the trie until we get to the right subtrie for the string, then
  68.      * add the value.  If we hit a KT_DEF, expand the trie.  If we hit a KT_VAL
  69.      * change it to a KT_TVAL, which times out as a KT_VAL but continues as a
  70.      * KT_TRIE.  If given a value for a KT_TRIE, change it to a KT_TVAL.
  71.      */
  72.     if (!str || !*str)
  73.     return;            /* no key to define */
  74.     old = str;
  75.     t = keys;
  76.     while (str[1])
  77.     {
  78.     c = uchar(*str++);
  79.     if (t[c].kt_type != KT_TRIE)
  80.     {
  81.         if (t[c].kt_type == KT_DEF)
  82.         t[c].kt_type = KT_TRIE;
  83.         else
  84.         {
  85.         t[c].kt_type = KT_TVAL;
  86.         t[c].kt_tval = t[c].kt_val;
  87.         }
  88.         t[c].kt_trie = mallocw(256 * sizeof (struct keytrie));
  89.         for (i = 256; i--; )
  90.         {
  91.         t[c].kt_trie[i].kt_type = KT_DEF;
  92.         t[c].kt_trie[i].kt_val = i;
  93.         }
  94.     }
  95.     t = t[c].kt_trie;
  96.     }
  97.     c = uchar(*str);
  98.     if (t[c].kt_type == KT_TRIE)
  99.     {
  100.     t[c].kt_type = KT_TVAL;
  101.     t[c].kt_tval = val;
  102.     }
  103.     else if (t[c].kt_type == KT_DEF)
  104.     {
  105.     t[c].kt_type = KT_VAL;
  106.     t[c].kt_val = val;
  107.     }
  108. }
  109.  
  110. static int
  111. raw_init(const struct sessmgr_sw *sm)
  112. {
  113.     extern int Numrows, Numcols;
  114.  
  115.     if (infoed)
  116.     set_curterm(my_term);
  117.     else
  118.     {
  119.     /*
  120.      * By rights we should use curses' setup, but then it becomes harder
  121.      * to configure either out.  Waste a little memory for now; it's not
  122.      * going to be much more than the size of the terminfo file, which
  123.      * is itself rarely more than 1.5K.
  124.      */
  125.     setupterm(0, 1, 0);
  126.     my_term = cur_term;
  127.     /* load keytrie */
  128.     key_init();
  129.     key_add(key_down, DNARROW);
  130.     key_add(key_f1, -3);
  131.     key_add(key_f2, -4);
  132.     key_add(key_f3, -5);
  133.     key_add(key_f4, -6);
  134.     key_add(key_f5, -7);
  135.     key_add(key_f6, -8);
  136.     key_add(key_f7, -9);
  137.     key_add(key_f8, -10);
  138.     key_add(key_f9, -11);
  139. #ifdef M_UNIX
  140.     /* SCO botches it, as per usual */
  141.     key_add(key_f0, -2);
  142. #else
  143.     key_add(key_f10, -2);
  144. #endif
  145.     key_add(key_left, LTARROW);
  146.     key_add(key_right, RTARROW);
  147.     key_add(key_up, UPARROW);
  148.     key_add("\177", '\b');    /* so DEL behaves as BS */
  149.     infoed = 1;
  150.     }
  151.     if (tcgetattr(0, &old_tty) == -1)
  152.     return 0;
  153.     new_tty = old_tty;
  154.     new_tty.c_lflag &= ~(ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHONL);
  155.     new_tty.c_cc[VMIN] = 1;
  156.     new_tty.c_cc[VTIME] = 0;
  157.     tcsetattr(0, TCSADRAIN, &new_tty);
  158.     Numrows = lines;
  159.     Numcols = columns;
  160.     putp(enter_ca_mode);
  161.     return 1;
  162. }
  163.  
  164. static void
  165. raw_end(const struct sessmgr_sw *sm)
  166. {
  167.     if (!Suspense)
  168.     {
  169.     putp(exit_ca_mode);
  170.     tcsetattr(0, TCSADRAIN, &old_tty);
  171.     }
  172. }
  173.  
  174. static void
  175. raw_suspend(const struct sessmgr_sw *sm)
  176. {
  177.     if (!Suspense++)
  178.     {
  179.     putp(exit_ca_mode);
  180.     fflush(stdout);
  181.     tcsetattr(0, TCSADRAIN, &old_tty);
  182.     }
  183. }
  184.  
  185. static void
  186. raw_resume(const struct sessmgr_sw *sm)
  187. {
  188.     extern int Numrows, Numcols;
  189.  
  190.     if (!--Suspense)
  191.     {
  192.     tcsetattr(0, TCSADRAIN, &new_tty);
  193.     set_curterm(my_term);
  194.     Numrows = lines;
  195.     Numcols = columns;
  196.     putp(enter_ca_mode);
  197.     }
  198. }
  199.  
  200. static int
  201. raw_swap(const struct sessmgr_sw *sm, void *old, void *new)
  202. {
  203.     int c;
  204.  
  205.     if (old && new)
  206.     {
  207.     c = (int) new - 1;
  208.     putp(clear_screen);
  209.     printf(">>> switching to session %d", c);
  210.     if (Sessions[c].name && *Sessions[c].name)
  211.         printf(": %s", Sessions[c].name);
  212.     else if (Sessions[c].proc->name && *Sessions[c].proc->name)
  213.         printf(" [%s]", Sessions[c].proc->name);
  214.     printf(" (%s)\n", Sestypes[Sessions[c].type]);
  215.     }
  216.     return 0;            /* only the current session can do output */
  217. }
  218.  
  219. static void
  220. raw_putch(const struct sessmgr_sw *sm, void *dp, int c)
  221. {
  222.     putchar(c);
  223. }
  224.  
  225. static void
  226. raw_clreol(const struct sessmgr_sw *sm, void *dp)
  227. {
  228.     putp(clr_eol);
  229. }
  230.  
  231. static void
  232. raw_flush(const struct sessmgr_sw *sm, void *dp)
  233. {
  234.     if (!Suspense)
  235.     fflush(stdout);
  236. }
  237.  
  238. static void *
  239. raw_create(const struct sessmgr_sw *sm, struct session *sp)
  240. {
  241.     return (void *) (sp - Sessions + 1);
  242. }
  243.  
  244. static void
  245. raw_destroy(const struct sessmgr_sw *sm, void *dp)
  246. {
  247. }
  248.  
  249. static void
  250. raw_clrscr(const struct sessmgr_sw *sm, void *dp)
  251. {
  252.     putp(clear_screen);
  253. }
  254.  
  255. static int
  256. raw_wherex(const struct sessmgr_sw *sm, void *dp)
  257. {
  258.     return -1;
  259. }
  260.  
  261. static int
  262. raw_wherey(const struct sessmgr_sw *sm, void *dp)
  263. {
  264.     return -1;
  265. }
  266.  
  267. static void
  268. raw_window(const struct sessmgr_sw *sm, void *dp, int x1, int y1, int x2,
  269.           int y2)
  270. {
  271. }
  272.  
  273. static void
  274. raw_gotoxy(const struct sessmgr_sw *sm, void *dp, int x, int y)
  275. {
  276.     putp(tparm(cursor_address, y - 1, x - 1));
  277. }
  278.  
  279. static void
  280. raw_high(const struct sessmgr_sw *sm, void *dp)
  281. {
  282.     vidattr(A_REVERSE);
  283. }
  284.  
  285. static void
  286. raw_norm(const struct sessmgr_sw *sm, void *dp)
  287. {
  288.     vidattr(A_NORMAL);
  289. }
  290.  
  291. static void
  292. raw_cursor(const struct sessmgr_sw *sm, void *dp, int c)
  293. {
  294.     switch (c)
  295.     {
  296.     case _NOCURSOR:
  297.     putp(cursor_invisible);
  298.     break;
  299.     case _NORMALCURSOR:
  300.     putp(cursor_normal);
  301.     break;
  302.     case _SOLIDCURSOR:
  303.     putp(cursor_visible);
  304.     break;
  305.     }
  306. }
  307.  
  308. /*
  309.  * Same as for curses... probably ought to share them
  310.  */
  311.  
  312. static int
  313. kbchar(int ir)
  314. {
  315.     extern int Keyboard;
  316.     unsigned char ch;
  317.     int i;
  318.  
  319.     if (ir)
  320.     j_alarm(500);
  321.     do
  322.     {
  323.     if (pwait(&Keyboard) != 0 && ir)
  324.         return -1;
  325.     }
  326.     while ((i = read(0, &ch, 1)) == 0 || (i == -1 && errno == EWOULDBLOCK));
  327.     j_alarm(0);
  328.     if (i < 0)
  329.     {
  330.     tprintf("NOS PANIC: Lost keyboard\n");
  331.     where_outta_here(1);
  332.     }
  333.     return ch;
  334. }
  335.  
  336. static int
  337. raw_kbread(const struct sessmgr_sw *sm, void *dp)
  338. {
  339.     static int ungets[10];
  340.     struct keytrie *t;
  341.     static int unget;
  342.     int ungetc[10];
  343.     int c, i, u;
  344.  
  345.     i = 0;
  346.     u = 0;
  347.     if (unget > i)
  348.     c = ungets[i++];
  349.     else
  350.     c = kbchar(0);
  351.     ungetc[u++] = c;
  352.     t = keys;
  353.     while (t[c].kt_type == KT_TRIE || t[c].kt_type == KT_TVAL)
  354.     {
  355.     t = t[c].kt_trie;
  356.     if (unget > i)
  357.         c = ungets[i++];
  358.     else
  359.         c = kbchar(1);
  360.     if (c == -1)
  361.         break;
  362.     ungetc[u++] = c;
  363.     }
  364.     if (t[c].kt_type == KT_VAL)
  365.     {
  366.     u = 0;
  367.     c = t[c].kt_val;
  368.     }
  369.     else if (t[c].kt_type == KT_TVAL)
  370.     {
  371.     u = 0;
  372.     c = t[c].kt_tval;
  373.     }
  374.     while (i < unget)
  375.     ungetc[u++] = ungets[i++];
  376.     if (u)
  377.     {
  378.     c = ungetc[0];
  379.     for (i = u; i; i--)
  380.         ungets[i - 1] = ungetc[i];
  381.     unget = u - 1;
  382.     }
  383.     return c;
  384. }
  385.  
  386. struct sessmgr_sw raw_sessmgr =
  387. {
  388.     "raw",
  389.     SM_STDIO,
  390.     raw_init,
  391.     (char *(*)__FARGS((const struct sessmgr_sw *, char *))) 0,
  392.     raw_create,
  393.     (char *(*)__FARGS((const struct sessmgr_sw *, void *, char *))) 0,
  394.     raw_swap,
  395.     raw_putch,
  396.     raw_clreol,
  397.     raw_clrscr,
  398.     raw_wherex,
  399.     raw_wherey,
  400.     raw_window,
  401.     raw_gotoxy,
  402.     raw_high,
  403.     raw_norm,
  404.     raw_cursor,
  405.     raw_kbread,
  406.     raw_destroy,
  407.     raw_flush,
  408.     raw_suspend,
  409.     raw_resume,
  410.     raw_end,
  411. };
  412.  
  413. #endif
  414.